package com.example.dormitorysystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.dormitorysystem.entity.*;
import com.example.dormitorysystem.entity.pojo.StudentIdAndName;
import com.example.dormitorysystem.exception.CmsException;
import com.example.dormitorysystem.exception.ErrorCode;
import com.example.dormitorysystem.mapper.GroupsMapper;
import com.example.dormitorysystem.mapper.GroupsUserMapper;
import com.example.dormitorysystem.mapper.StudentInfoMapper;
import com.example.dormitorysystem.mapper.SysMapper;
import com.example.dormitorysystem.service.GroupsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Array;
import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 吉吉王国组
 * @since 2022-11-26
 */
@Service
public class GroupsServiceImpl extends ServiceImpl<GroupsMapper, Groups> implements GroupsService {

    @Resource
    private GroupsMapper groupsMapper;

    @Resource
    private GroupsUserMapper groupsUserMapper;

    @Resource
    private SysMapper sysMapper;

    @Resource
    private StudentInfoMapper studentInfoMapper;

    @Override
    @Transactional
    public Map<String, Object> setGroup(Map<String, Object> input, HttpServletRequest request, HttpServletResponse response) {
        //判断系统是否允许组队
        QueryWrapper<Sys> sysQueryWrapper = new QueryWrapper<>();
        sysQueryWrapper.eq("key_name", "group_limit");
        Sys sys = sysMapper.selectOne(sysQueryWrapper);
        if (sys.getKeyValue() == "1") {
            throw new CmsException(400, "系统不允许组队");
        }

        //记录输入的参数等
        String name = input.get("name").toString();
        String desc = input.get("describe").toString();
        Integer id = Integer.parseInt(request.getAttribute("uid").toString());

        //查询本人是否已经组队
        QueryWrapper<GroupsUser> groupsUserQueryWrapper = new QueryWrapper<>();
        groupsUserQueryWrapper.eq("uid", id);
        GroupsUser groupsUser = groupsUserMapper.selectOne(groupsUserQueryWrapper);
        //若已组队则结束
        if (groupsUser != null) {
            throw new CmsException(400, "您已组队，无法再次创建队伍");
        }

        //本人尚未组队 随机生成邀请码（唯一）
        Random r = new Random();
        Groups groups;
        Integer invite_code;
        //循环随机数 1000-9999，直到唯一为止
        do {
            invite_code = r.nextInt(9000) + 1000;
            QueryWrapper<Groups> groupsQueryWrapper = new QueryWrapper<>();
            groupsQueryWrapper.eq("invite_code", invite_code.toString());
            groups = groupsMapper.selectOne(groupsQueryWrapper);

        } while (groups != null);

        //记录队伍信息并插入到组队表
        groups = new Groups();
        groups.setId(invite_code);
        groups.setName(name);
        groups.setInviteCode(invite_code.toString());
        groups.setDescribes(desc);
        groupsMapper.insert(groups);

        //记录成员信息并插入到组队成员表
        groupsUser = new GroupsUser();
        groupsUser.setUid(id);
        groupsUser.setIsCreator(1);
        groupsUser.setGroupId(groups.getId());
        groupsUser.setJoinTime(new Date());
        groupsUser.setLeaveTime(new Date());
        groupsUserMapper.insert(groupsUser);

        //记录返回结果并返回
        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
        stringObjectHashMap.put("team_id", groups.getId());
        stringObjectHashMap.put("invite_code", invite_code);
        return stringObjectHashMap;

    }

    @Override
    public void delGroup(HttpServletRequest request, HttpServletResponse response) {
//        Integer teamId = (Integer) input.get("team_id");

        Integer uid = Integer.parseInt(request.getAttribute("uid").toString());

        GroupsUser groupsUser = groupsUserMapper.selectOneByUid(uid);

        //队伍还有人则不能删除
        //查询目标队伍当前总人数
        QueryWrapper<GroupsUser> groupsUserQueryWrapperTarget = new QueryWrapper<>();
        groupsUserQueryWrapperTarget.eq("group_id", groupsUser.getGroupId());
        Integer memberCount = groupsUserMapper.selectCount(groupsUserQueryWrapperTarget);
        if (memberCount > 1) {
            throw new CmsException(401, "队伍除您以外，还有其他人，队伍不能删除");
        }
        groupsUserMapper.deleteById(groupsUser.getId());
        //组队表中删除对应记录
        groupsMapper.deleteById(groupsUser.getGroupId());
    }

    @Override
    public Map<String, Object> joinGroup(Map<String, Object> input, HttpServletRequest request, HttpServletResponse response) {
        //判断系统是否允许组队
        QueryWrapper<Sys> sysQueryWrapper1 = new QueryWrapper<>();
        sysQueryWrapper1.eq("key_name", "group_limit");
        Sys sys = sysMapper.selectOne(sysQueryWrapper1);
        if (sys.getKeyValue() == "1") {
            throw new CmsException(400, "系统不允许组队");
        }

        //系统组队应该是需要同一性别才行
        //todo 在组队实体中添加性别


        //查询本人是否在任何队伍中
        Integer id = Integer.parseInt(request.getAttribute("uid").toString());
        QueryWrapper<GroupsUser> groupsUserQueryWrapperMy = new QueryWrapper<>();
        groupsUserQueryWrapperMy.eq("uid", id);
        GroupsUser groupsUser = groupsUserMapper.selectOne(groupsUserQueryWrapperMy);
        //若在其他队伍中
        if (groupsUser != null) {
            throw new CmsException(400, "您已在其他队伍中");
        }

        //通过邀请码 查询目标队伍（邀请码唯一）
        String invite_code = input.get("invite_code").toString();
        QueryWrapper<Groups> groupsQueryWrapper = new QueryWrapper<>();
        groupsQueryWrapper.eq("invite_code", invite_code);
        Groups groups = baseMapper.selectOne(groupsQueryWrapper);
        //目标队伍不存在
        if (groups == null) {
            throw new CmsException(401, "邀请码不存在");
        }

        //查询目标队伍当前总人数
        QueryWrapper<GroupsUser> groupsUserQueryWrapperTarget = new QueryWrapper<>();
        groupsUserQueryWrapperTarget.eq("group_id", groups.getId());
        Integer memberCount = groupsUserMapper.selectCount(groupsUserQueryWrapperTarget);
        //查询系统允许的最大组队人数
        QueryWrapper<Sys> sysQueryWrapper2 = new QueryWrapper<>();
        sysQueryWrapper2.eq("key_name", "group_num");
        sys = sysMapper.selectOne(sysQueryWrapper2);

        if (memberCount >= Integer.parseInt(sys.getKeyValue())) {
            throw new CmsException(402, "目标队伍人数已满，无法加入");
        }

        //将本人信息 插入到组队成员表
        groupsUser = new GroupsUser();
        groupsUser.setUid(id);
        groupsUser.setGroupId(groups.getId());
        groupsUser.setJoinTime(new Date());
        groupsUser.setLeaveTime(new Date());
        groupsUserMapper.insert(groupsUser);

        //返回队伍id
        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
        stringObjectHashMap.put("team_id", groups.getId());
        return stringObjectHashMap;

    }

    @Override
    public void quitGroup(HttpServletRequest request, HttpServletResponse response) {
//        Integer teamId = (Integer) input.get("team_id");
        Integer id = Integer.parseInt(request.getAttribute("uid").toString());

        //查询本人是否在目标队伍中
        QueryWrapper<GroupsUser> groupsUserQueryWrapper = new QueryWrapper<>();
        groupsUserQueryWrapper.eq("uid", id);
        GroupsUser groupsUser = groupsUserMapper.selectOne(groupsUserQueryWrapper);
        //若不在任何队伍中
        if (groupsUser == null) {
            throw new CmsException(400, "您不在任何队伍中");
        }

        //查询所在队伍id
        Integer teamId = groupsUser.getGroupId();

        //若不在目标队伍中
//        if (groupsUser.getGroupId() != teamId) {
//            throw new CmsException(401, "您不在该队伍中");
//        }

        //若是队长 无法直接退出队伍，仅在队伍只剩一人时可以退出
        if (groupsUser.getIsCreator() == 1) {
            //查询目标队伍当前总人数
            QueryWrapper<GroupsUser> groupsUserQueryWrapperCount = new QueryWrapper<>();
            groupsUserQueryWrapperCount.eq("group_id", teamId);
            Integer memberCount = groupsUserMapper.selectCount(groupsUserQueryWrapperCount);
            //队伍有其他人
            if (memberCount != 1) {
                throw new CmsException(402, "您是队长，且队伍中有其他成员，无法直接退出队伍，请在转让队长后重试");
            }
            //没有其他人 将队伍删除
            groupsMapper.deleteById(teamId);
        }

        //删除组队成员表中的记录
        groupsUserMapper.delete(groupsUserQueryWrapper);
    }

    @Override
    public Map<String, Object> myGroup(HttpServletRequest request, HttpServletResponse response) {
        Integer id = Integer.parseInt(request.getAttribute("uid").toString());
        HashMap<String, Object> stringObjectHashMap = new HashMap<>();

        //查询组队用户表
        QueryWrapper<GroupsUser> groupsUserQueryWrapper = new QueryWrapper<>();
        groupsUserQueryWrapper.eq("uid", id);
        GroupsUser groupsUser = groupsUserMapper.selectOne(groupsUserQueryWrapper);

        if (groupsUser == null) {
            throw new CmsException(401, "您不在任何队伍中");
        }

        //查询组队表
        QueryWrapper<Groups> groupsQueryWrapper = new QueryWrapper<>();
        groupsQueryWrapper.eq("id", groupsUser.getGroupId());
        Groups groups = groupsMapper.selectOne(groupsQueryWrapper);

        //记录输出信息
        stringObjectHashMap.put("group_id", groupsUser.getGroupId());
        stringObjectHashMap.put("group_name", groups.getName());
        stringObjectHashMap.put("invite_code", groups.getInviteCode());

        //记录队伍成员的id和name
        List<StudentIdAndName> members = new LinkedList<>();
        List<Users> users = groupsUserMapper.selectRoommateByGroupId(groupsUser.getGroupId());
        for (Users user : users) {
            StudentIdAndName studentIdAndName = new StudentIdAndName(user.getUid(), user.getName());
            members.add(studentIdAndName);
        }
        stringObjectHashMap.put("members", members);

        //返回
        return stringObjectHashMap;
    }

    @Override
    public void transGroup(Map<String, Object> input, HttpServletRequest request, HttpServletResponse response) {
        //查询欲转让的目标学生的组队信息
        //通过学号 在学生信息表里 查询用户
        String stuId = input.get("student_id").toString();
        QueryWrapper<StudentInfo> studentInfoQueryWrapper = new QueryWrapper<>();
        studentInfoQueryWrapper.eq("studentid", stuId);
        StudentInfo studentInfo = studentInfoMapper.selectOne(studentInfoQueryWrapper);

        //对方不存在
        if (studentInfo == null) {
            throw new CmsException(401, "该学号不存在");
        }

        //利用学生信息表的uid 在组队成员表里进行筛选
        QueryWrapper<GroupsUser> groupsUserQueryWrapperTrans = new QueryWrapper<>();
        Integer transId = studentInfo.getUid();
        groupsUserQueryWrapperTrans.eq("uid", transId);
        GroupsUser groupsUserTrans = groupsUserMapper.selectOne(groupsUserQueryWrapperTrans);

        //对方不在队伍中
        if (groupsUserTrans == null) {
            throw new CmsException(402, "对方不在任何队伍中");
        }

        //查询本人的组队信息
        Integer myId = Integer.parseInt(request.getAttribute("uid").toString());
        QueryWrapper<GroupsUser> groupsUserQueryWrapperMy = new QueryWrapper<>();
        groupsUserQueryWrapperMy.eq("uid", myId);
        GroupsUser groupsUserMy = groupsUserMapper.selectOne(groupsUserQueryWrapperMy);

        //本人不在队伍中
        if (groupsUserMy == null) {
            throw new CmsException(403, "您不在任何队伍中");
        }

        //两人不在同一队伍里
        if (groupsUserTrans.getGroupId() != groupsUserMy.getGroupId()) {
            throw new CmsException(404, "您和对方不在同一队伍中");
        }

        //本人不是队长
        if (groupsUserMy.getIsCreator() == 0) {
            throw new CmsException(405, "您不是队长");
        }

        //修改队长值并更新数据库
        groupsUserTrans.setIsCreator(1);
        groupsUserMy.setIsCreator(0);
        groupsUserMapper.updateById(groupsUserTrans);
        groupsUserMapper.updateById(groupsUserMy);

    }


}
